package bll

import (
	"context"
	"time"

	"gorm.io/gorm"
	"manager/errors"
	"manager/store/postgres"
	"manager/utils"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
)

type area struct {
	iArea store.IArea
}

var Area = &area{}

func (a *area) init() func() {
	a.iArea = postgres.Area
	return func() {}
}

func (a *area) onEvent(*event.Data) {}

func (a *area) Create(ctx context.Context, in *model.AreaCreateRequest) error {
	var (
		err error
	)

	// 查询区域是否存在
	_, err = a.iArea.FindByName(ctx, in.Name)
	if err != nil && err != gorm.ErrRecordNotFound {
		return errors.AreaCreateFailed.Error()
	}

	// 创建区域
	c := buildArea(in)
	_, err = a.iArea.Create(ctx, c)
	return err
}

func (a *area) Update(ctx context.Context, in *model.AreaUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
		err  error
		ety  *entity.Area
	)
	if in.ID == nil || *in.ID == 0 {
		return errors.ParameterErr.Error()
	}

	ety, err = a.iArea.Find(ctx, *in.ID)
	if err != nil && errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.AreaNotFound.Error()
	}

	if *in.Name == ety.Name {
		return errors.AreaNameDuplicated.Error()
	}

	if in.Name != nil {
		dict["name"] = *in.Name
	}

	if in.Desc != nil {
		dict["desc"] = *in.Desc
	}
	// do other update here

	return a.iArea.Update(ctx, *in.ID, dict)
}

func (a *area) Delete(ctx context.Context, in *model.AreaDeleteRequest) error {
	// 判断一下区域是否有门店
	list, _ := StoreServer.iStore.CountByArea(ctx, []int64{in.ID})
	if len(list) > 0 {
		return errors.New("区域下有门店，不能删除")
	}
	return a.iArea.Delete(ctx, in.ID)
}

func (a *area) List(ctx context.Context, in *model.AreaListRequest) (*model.AreaListResponse, error) {
	var (
		err     error
		total   int
		list    []*entity.Area
		byArea  []*model.CountByAreaResponse
		out     = &model.AreaListResponse{}
		outList = make([]*model.AreaInfo, 0)
	)
	in.Size, in.Index = utils.PageUtil(in.Size, in.Index)

	if total, list, err = a.iArea.List(ctx, in); err != nil {
		return out, err
	}
	if len(list) == 0 {
		return out, err
	}
	ids := make([]int64, len(list))

	for i, e := range list {
		ids[i] = e.ID
		outList = append(outList, &model.AreaInfo{
			ID:        e.ID,
			Name:      e.Name,
			Desc:      e.Desc,
			CreatedAt: e.CreatedAt,
			UpdatedAt: e.UpdatedAt,
		})
	}

	// 查询门店数量
	byArea, err = StoreServer.iStore.CountByArea(ctx, ids)
	if err != nil {
		return out, err
	}

	// 装配数据
	for i, areas := range outList {
		for _, areaCount := range byArea {
			if areas.ID == areaCount.AreaId {
				outList[i].StoreCount = areaCount.Count
			}
		}
	}

	// 查询销售数量

	out.Total = total
	out.Data = outList

	return out, nil
}

func buildArea(in *model.AreaCreateRequest) *entity.Area {
	// todo: check the entity is required
	return &entity.Area{

		Name: in.Name,

		Desc: in.Desc,

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
